/*

The contents of this web application are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this web application except in compliance with the License. 
You may obtain a copy of the License at http://www.mozilla.org/MPL/.

Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 
See the License for the specific language governing rights and limitations under the License.

The Original Code is owned by and the Initial Developer of the Original Code is Composite A/S (Danish business reg.no. 21744409). All Rights Reserved

Section 11 of the License is EXPRESSLY amended to include a provision stating that any dispute, including but not limited to disputes related to the enforcement of the License, to which Composite A/S as owner of the Original Code, as Initial Developer or in any other role, becomes a part to shall be governed by Danish law and be initiated before the Copenhagen City Court ("K�benhavns Byret")
                        
*/

BindingParser.XML = "<div xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:ui=\"http://www.w3.org/1999/xhtml\">${markup}</div>";

/**
 * @class
 * Parses markup into elements with all bindings preregistered.
 * @param {DOMDocument} ownerDocument
 */
function BindingParser ( ownerDocument ) {
	
	/**
	 * @type {SystemLogger}
	 */
	this.logger = SystemLogger.getLogger ( "BindingParser" );
	
	/**
	 * @type {DOMDocument}
	 */
	this._ownerDocument = ownerDocument;
	
	/**
	 * @type {DOMElement}
	 */
	this._rootElement = null;
}

/**
 * Since incoming markup may not be placed in a single root element, 
 * this method returns a list of elements. Normally you would   
 * return a DOMDocumentFragment, but IE doesn't handle those. Notice 
 * that we return a list of elements, not bindings.
 * @param {string} markup
 * @return {List<DOMElement>}
 */
BindingParser.prototype.parseFromString = function ( markup ) {
	
	var result = new List ();
	var xml = BindingParser.XML.replace ( "${markup}", markup );
	var doc = XMLParser.parse ( markup );
	
	if ( doc ) {
		var solidroot = DOMUtil.createElementNS ( 
			Constants.NS_XHTML, 
			"div", 
			this._ownerDocument 
		);
		this._iterate ( doc.documentElement, solidroot );
		var node = solidroot.firstChild;
		while ( node ) {
			if ( node.nodeType == Node.ELEMENT_NODE ) {
				result.add ( node );
			}
			node = node.nextSibling;
		}
	}
	return result;
}

/**
 * Iterate an "abstract" DOM document and produce a solid XHTML nodetree.
 * @param {DOMNode} abstract
 * @param {DOMElement} collector
 */
BindingParser.prototype._iterate = function ( abstractnode, collector ) {
	
	var solidnode = null;

	switch ( abstractnode.nodeType ) {
		case Node.ELEMENT_NODE :
			solidnode = this._cloneElement ( abstractnode );
			UserInterface.registerBinding ( solidnode );
			break;
		case Node.TEXT_NODE :		
			solidnode = this._ownerDocument.createTextNode ( abstractnode.nodeValue );
			break;
	}
	if ( solidnode ) {
		collector.appendChild ( solidnode );
	}
	if ( solidnode && abstractnode.hasChildNodes ()) { // SOLIDNODE?
		var child = abstractnode.firstChild;
		while ( child ) {
			this._iterate ( child, solidnode );
			child = child.nextSibling;
		}
	}
};

/**
 * Clone element and attributes from "abstract" node and return a solid XHTML node.
 * @param {DOMElement} abstractnode
 * @return {DOMElement}
 */
BindingParser.prototype._cloneElement = function ( abstractnode ) {
	
	/*
	 * Notice that null namespaces gets converted to XHTML because of Atlas fugup.
	 */
	var solidnode = DOMUtil.createElementNS (
		abstractnode.namespaceURI ? abstractnode.namespaceURI : Constants.NS_XHTML, 
		abstractnode.nodeName, 
		this._ownerDocument 
	);
	var i = 0;
	while ( i < abstractnode.attributes.length ) {
		var attr = abstractnode.attributes.item ( i++ );
		solidnode.setAttribute ( attr.nodeName, String ( attr.nodeValue ));
	}
	return solidnode;
}

/**
 * Register binding if applicable.
 * @param {DOMElement} abstractnode
 * @param {DOMElement} solidnode
 *
BindingParser.prototype._registerBinding = function ( abstractnode, solidnode ) {
	
	UserInterface.registerBinding ( solidnode );
	if ( abstractnode.prefix && abstractnode.prefix == "ui" ) {
		var name = DOMUtil.getLocalName ( abstractnode );
		var impl = null;
		if ( abstractnode.getAttribute ( "binding" ) != null ) {
			impl = eval ( abstractnode.getAttribute ( "binding" ));
		} else {
			impl = BindingParser.map [ name ];
		}
		if ( impl ) {
			UserInterface.registerBinding ( solidnode, impl );
		}
	}
}
*/